package com.srini.servlets;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.util.CellRangeAddress;

import com.srini.pojos.LoggedInUser;
import com.srini.util.AppUtil;
import com.srini.util.ConnectionUtil;
import com.srini.util.LeaveHolyDays;

public class TimeSheet extends HttpServlet {

	private static final long serialVersionUID = 1L;
	

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		doPost(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		String from = req.getParameter("from");
		String to = req.getParameter("to");
		String fromHrs = req.getParameter("fromHrs");
		String toHrs = req.getParameter("toHrs");
		String[] months = { "January", "February", "March", "April", "May",
				"June", "July", "August", "September", "October", "November",
				"December" };

		LoggedInUser user = (LoggedInUser) req.getSession().getAttribute("loggedInUser");
		String userName = user.getUserInfo().getFullName();
		
		if (AppUtil.isEmpty(userName)) {
			userName = user.getUserName();
		}
		if (AppUtil.isEmpty(user.getUserInfo().getDistanceFromHome()) || AppUtil.isEmpty(user.getUserInfo().getVehicle())) {
			String message = "Error::You need to fill your details before generating reports.";
			req.setAttribute("message",message);
			req.setAttribute("currentPage", "userprofile");
			req.getRequestDispatcher("/main.jsp").forward(req, resp);
			return;
		}
		Date fromDate = null, toDate = null;
		try {
			fromDate = AppUtil.DATE_FORMAT_MEDIUM.parse(from);
			toDate = AppUtil.DATE_FORMAT_MEDIUM.parse(to);
		} catch (Exception e) {
			e.printStackTrace();
		}
		Map leaves = LeaveHolyDays.getHolidays(user.getId(),
				new ConnectionUtil().getConnection());

		Calendar startCal;
		Calendar endCal;
		startCal = Calendar.getInstance();
		startCal.setTime(fromDate);
		endCal = Calendar.getInstance();
		endCal.setTime(toDate);
		resp.setContentType("application/vnd.ms-excel");
		InputStream is = this.getClass().getResourceAsStream("/TimeSheet.xls");
		HSSFWorkbook wb = new HSSFWorkbook(is);
		HSSFSheet sheet = wb.getSheetAt(0);

		// Create a row and put some cells in it. Rows are 0 based.
		HSSFRow row = sheet.getRow(0);
		// Create a cell and put a value in it.
		HSSFCell cell = row.getCell(1);
		cell.setCellValue(user.getUserInfo().getEmpId());
		cell.setAsActiveCell();
		row = sheet.getRow(1);
		cell = row.getCell(1);
		cell.setCellValue(user.getUserInfo().getFullDisplayName());

		// Write the output
		OutputStream out = resp.getOutputStream();

		String fileName = userName + "_TimeSheet_"
				+ startCal.get(Calendar.DAY_OF_MONTH) + "_"
				+ endCal.get(Calendar.DAY_OF_MONTH) + "_"
				+ months[startCal.get(Calendar.MONTH)]
				+ startCal.get(Calendar.YEAR) + ".xls";
		HSSFCellStyle style = wb.createCellStyle();
		style.setFillForegroundColor(HSSFColor.GREY_25_PERCENT.index);
		style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
		style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		style.setBorderBottom((short) 1);
		style.setBorderRight((short) 1);
		int rowStart = 4;
		while (startCal.before(endCal)) {
			row = sheet.getRow(rowStart);
			
			addDataToCell(startCal, row, fromHrs, toHrs, wb, style, sheet, leaves);
			rowStart++;
			startCal.add(Calendar.DAY_OF_MONTH, 1);
		}
		row = sheet.getRow(rowStart);
		addDataToCell(endCal, row, fromHrs, toHrs, wb, style, sheet, leaves);
		resp.setHeader("Content-Disposition", "attachment; filename="
				+ fileName);
		wb.write(out);
		out.close();
	}

	private void addDataToCell(Calendar startCal, HSSFRow row, String fromHrs,
			String toHrs, HSSFWorkbook wb, HSSFCellStyle style, HSSFSheet sheet, Map days) {

		String date = AppUtil.DATE_FORMAT_MEDIUM.format(startCal.getTime());
		int day = 0;
		List leaves =(List) days.get("0");
		List holidays = (List)days.get("1");
		row.getCell(0).setCellValue(startCal);
		String[] weeks = { "", "Sunday", "Monday", "Tuesday", "Wednesday",
				"Thursday", "Friday", "Saturday" };
		int rowNum = row.getRowNum() + 1;
		int dayOfWeek = startCal.get(Calendar.DAY_OF_WEEK);
		if (dayOfWeek == Calendar.SATURDAY || dayOfWeek == Calendar.SUNDAY) {
			day = 1;
		} else if (leaves != null && leaves.contains(date)) {
			day = 2;
		} else if (holidays != null && holidays.contains(date)){
			day = 3;
		}
		HSSFCellStyle clonedStyle = wb.createCellStyle();
		clonedStyle.cloneStyleFrom(style);
		switch (day) {
		case 1:
			String weekend = weeks[startCal.get(Calendar.DAY_OF_WEEK)];
			mergeCells(startCal, row, sheet, style, weekend);
			break;

		case 2:
			clonedStyle
			.setFillForegroundColor(HSSFColor.LIGHT_CORNFLOWER_BLUE.index);
			mergeCells(startCal, row, sheet, clonedStyle, "Leave");
			break;
		case 3:
			clonedStyle.setFillForegroundColor(HSSFColor.LIGHT_GREEN.index);
			mergeCells(startCal, row, sheet, clonedStyle, "Holiday");
			break;
		default:
			row.getCell(1).setCellValue(fromHrs);
			row.getCell(2).setCellValue(toHrs);
			String formulae = "IF(C" + rowNum + "<B" + rowNum + ", C" + rowNum
					+ "+1, " + "C" + rowNum + ")- B" + rowNum;
			row.getCell(3).setCellFormula(formulae);
			break;
		}
	}

	private void mergeCells(Calendar startCal, HSSFRow row, HSSFSheet sheet,
			HSSFCellStyle style, String text) {
		CellRangeAddress add = new CellRangeAddress(row.getRowNum(),
				row.getRowNum(), 1, 3);
		sheet.addMergedRegion(add);
		row.getCell(1).setCellValue(text);
		row.getCell(1).setCellStyle(style);
		row.getCell(2).setCellStyle(style);
		row.getCell(3).setCellStyle(style);

	}
}
